/*
 * commons is a based project implemented
 * Copyright (C) 2024 Jasmine
 */
package com.easy.core.validator;

import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

import java.lang.annotation.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.springframework.util.StringUtils;

import jakarta.validation.Constraint;
import jakarta.validation.ConstraintValidator;
import jakarta.validation.ConstraintValidatorContext;
import jakarta.validation.Payload;

/**
 * 手机验证
 *
 * @author Jasmine
 * @since 1.0.0
 */
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.METHOD})
@Constraint(validatedBy = PhoneValidator.PhoneValidatorHandle.class)
public @interface PhoneValidator {
    Pattern MOBILE = Pattern.compile("(?:0|86|\\+86)?1[3-9]\\d{9}");

    String message() default "手机号码格式不正确";

    Class[] groups() default {};

    Class<? extends Payload>[] payload() default {};

    boolean required() default true;

    @Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE})
    @Retention(RUNTIME)
    @Documented
    @interface List {
        PhoneValidator[] value();
    }

    class PhoneValidatorHandle implements ConstraintValidator<PhoneValidator, String> {

        private Boolean required;

        @Override
        public void initialize(PhoneValidator constraintAnnotation) {
            this.required = constraintAnnotation.required();
        }

        @Override
        public boolean isValid(String phoneValue, ConstraintValidatorContext constraintValidatorContext) {
            if (!StringUtils.hasLength(phoneValue)) {
                // 校验是不是必填
                if (required) {
                    return false;
                } else {
                    return true;
                }
            } else {
                Matcher m = MOBILE.matcher(phoneValue);
                boolean isMatch = m.matches();
                return isMatch;
            }
        }
    }

}
